package net.cassite.pure.ioc.handlers.type;

import java.lang.annotation.Annotation;

import net.cassite.pure.aop.AOP;
import net.cassite.pure.aop.AOPController;
import net.cassite.pure.ioc.AnnotationHandlingException;
import net.cassite.pure.ioc.Scope;
import net.cassite.pure.ioc.Utils;
import net.cassite.pure.ioc.handlers.TypeAnnotationHandler;
import net.cassite.pure.ioc.handlers.TypeHandlerChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TypeAOPHandler implements TypeAnnotationHandler {

        private static final Logger LOGGER = LoggerFactory.getLogger(TypeAOPHandler.class);

        @Override
        public boolean canHandle(Annotation[] annotations) {
                return Utils.getAnno(AOP.class, annotations) != null;
        }

        @Override
        @SuppressWarnings("unchecked")
        public Object handle(Scope scope, Class<?> cls, Class<?> expectedClass, TypeHandlerChain chain) throws AnnotationHandlingException {
                LOGGER.debug("Entered TypeAOPHandler with args: \n\tcls:\t{}\n\tchain:\t{}", cls, chain);
                Object o = chain.next().handle(scope, cls, expectedClass, chain);
                LOGGER.debug("start handling with TypeAOPHandler");
                LOGGER.debug("retrieved instance is {}", o);
                if (o == null)
                        throw new AnnotationHandlingException("cannot weave to null");
                Object r = AOPController.weave(scope, () -> o, (Class<Object>) expectedClass);
                LOGGER.debug("generated proxy object is {}", r);
                return r;
        }

}
